package top.winshu.common.util;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import top.winshu.common.exception.WinshuException;
import top.winshu.common.lang.Snowflake;

import java.util.Date;
import java.util.UUID;

/**
 * @author winshu
 * @since 2021/1/28
 **/
public class IdGenerator {

    private static final Logger LOGGER = LoggerFactory.getLogger(IdGenerator.class);
    private static Snowflake snowflake;

    public static void init(int machineId) {
        if (machineId >= 1024 || machineId <= 0) {
            throw new IllegalArgumentException("机器编号的设置范围为(1-1023)，当前值为=" + machineId);
        }
        if (snowflake == null) {
            // 1-1023, 0为缺省使用
            // 前5位为 datacenterid, 后5位为 workid
            snowflake = new Snowflake(machineId & 0x1F, machineId >> 5);
            LOGGER.info(">>>>> 初始化全局ID生成器，机器ID({})", machineId);
        }
    }

    public static String uuid() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    public static long newId() {
        return getSnowflake().nextId();
    }

    public static Date getDateTime(long id) {
        long timestamp = getSnowflake().getGenerateDateTime(id);
        return new Date(timestamp);
    }

    public static String newId(String latestId, String defaultId) {
        if (latestId == null || latestId.length() == 0) {
            return defaultId;
        }

        String prefix = latestId.substring(0, 2);
        int latestIndex = Integer.parseInt(latestId.substring(2));
        int max = (int) Math.pow(10, latestId.length() - 2);
        if (latestIndex + 1 >= max) {
            throw new WinshuException("ID out of max range");
        }

        String format = prefix + "%0" + (latestId.length() - 2) + "d";
        return String.format(format, latestIndex + 1);
    }

    public static boolean isLongId(String value) {
        if (StringUtils.isEmpty(value) || value.length() != 19) {
            return false;
        }
        for (int i = 0; i < value.length(); i++) {
            if (!Character.isDigit(value.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    private static Snowflake getSnowflake() {
        if (snowflake == null) {
            throw new WinshuException("ID生成器尚未初始化，请调用 IdGenerator.init 进行初始化");
        }
        return snowflake;
    }

}
